﻿/*
 * 數據格式
----V,------nA,----
----V,------nA,----
----V,------nA,----
----V,------nA,----
----V,------nA,----
16.0V, 0.000mA,PASS
16.0V,  0.00uA,PASS
16.0V,0.0000mA,PASS
16.0V,0.0000uA,PASS
 0.3V,  0.00uA,PASS

 * */

using GKQC.Common;
using GKQC.DbHelper.DbModels;
using GKQC.DbHelper.ViewModels;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;

namespace GKQC.Machine
{
    public partial class FormLC2311 : QcFormBase, IMachine
    {
        int _RowIndex = 0;
        //DataGridView grid;
        bool isTestting = false;
        bool isDischarging = false;
        bool isGettingData = false;
        string stringPass = "PASS";
        ILcMeter lcMeter;
        List<ElectricViewModel> _ElectricViewModels;
        int _CurrentRowIndex = 0;
        StandardView _StandardView;
        Form parentForm;
        UserModel _User;
        ReportSetModel _Report;
        bool isDischarged = true;
        public bool IsClosing { get; set; }
        public FormLC2311(Form parentForm, UserModel user, double voltage, List<ElectricViewModel> electricViewModels, StandardView standardView
            , ReportSetModel report)
        {
            InitializeComponent();
            this._Report = report;
            this.parentForm = parentForm;
            this._User = user;
            this._StandardView = standardView;
            this.Grid.AutoGenerateColumns = false;
            this.Grid.CellFormatting +=
                 new System.Windows.Forms.DataGridViewCellFormattingEventHandler(DataGridViewSet.CellFormatting);
            this.Grid.CellFormatting +=
                 new DataGridViewCellFormattingEventHandler(DataGridViewSet.CellFormattingForColor);
            this.Grid.RowPostPaint += new DataGridViewRowPostPaintEventHandler(DataGridViewSet.RowPostPaint);
            this._ElectricViewModels = electricViewModels;
            Grid.DataSource = new BindingList<ElectricViewModel>(this._ElectricViewModels);
            this._StandardView = standardView;
            if (voltage <= 0) voltage = 5;
            numVoltage.Value = Convert.ToDecimal(voltage);
            int num = Tools.GetDoubleNum(voltage);
            if (num >= 0) numVoltage.DecimalPlaces = num;
            lcMeter = new LcMeter2311();

#if DEBUG
            //lcMeter = new LcMeterDebug();
#endif
            InitComBox();
            GetPortBuad();

            if (report.HasLc2)
                SetLc2Visible(true);

            cboLevel.SelectedIndexChanged += new System.EventHandler(cboLevel_SelectedIndexChanged);

            if (ChargeTime > 0 && ChargeTime != 60) numChargeTime.Value = ChargeTime;

            GetDefaultValue();


            try
            {
                if (!this.sp.IsOpen) listenComPort(sp, null, 9600);
                if (this.sp.IsOpen)
                {
                    Thread.Sleep(200);
                    lcMeter.ControlMachine(sp);
                    Thread.Sleep(200);
                    lcMeter.SetVoltage(sp, Convert.ToDecimal(voltage));
                    Thread.Sleep(50);
                    cboLevel_SelectedIndexChanged(cboLevel, new EventArgs());
                    Thread.Sleep(50);
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        void GetDefaultValue()
        {
            try
            {
                var lcdefaultS = Settings.GetDataObjectFile<string>(this.Name);
                if (string.IsNullOrWhiteSpace(lcdefaultS)) return;

                var lcdefault = JsonHelper.ToObject<LcDefaultValue>(lcdefaultS);
                if (lcdefault != null)
                {
                    if (lcdefault.ChargeTime > 0) numChargeTime.Value = lcdefault.ChargeTime;
                    if (lcdefault.LevelIndex > 0 && cboLevel.Items.Count > lcdefault.LevelIndex)
                        cboLevel.SelectedIndex = lcdefault.LevelIndex;
                }

                if (parentForm != null && (parentForm.Name == "FormOrt" || parentForm.Name == "FormLCR11022"))
                    numDischargeTime.Value = 5;
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
            }
        }
        void SaveDefaultValue()
        {
            try
            {
                LcDefaultValue defaultValue = new LcDefaultValue();
                defaultValue.LevelIndex = cboLevel.SelectedIndex;
                defaultValue.ChargeTime = numChargeTime.Value;
                Settings.SaveObject(defaultValue.ToJson(), this.Name);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        void InitComBox()
        {
            DataTable dt = MachineFactory.GetLcLevelTable();
            cboLevel.DisplayMember = "Name";
            cboLevel.ValueMember = "Value";
            cboLevel.DataSource = dt;
        }

        //設定
        private void btnSet_Click(object sender, EventArgs e)
        {
            try
            {
                btnCharge.Enabled = false;
                timer1.Enabled = false;
                string result = string.Empty;
                if (!this.sp.IsOpen) listenComPort(sp, null, 9600);
                if (this.sp.IsOpen)
                {
                    Thread.Sleep(200);
                    lcMeter.ControlMachine(sp);

                    string level = FormCommon.GetDataTableComboBoxValue(cboLevel);

                    lcMeter.SetLeak(sp, level);
                    lcMeter.SetVoltage(sp, numVoltage.Value);

                    if (numChargeTime.Value > 0)
                    {
                        lcMeter.SetCharTime(sp, numChargeTime.Value);
                    }

                    if (numDischargeTime.Value > 0)
                    {
                        lcMeter.SetDisChargeTime(sp, numDischargeTime.Value);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                MessageBox.Show(ex.Message);
            }
            finally
            {
                btnCharge.Enabled = true;
            }
        }

        private bool listenComPort(System.IO.Ports.SerialPort serialPort, string portName, int BaudRate)
        {
            try
            {
                serialPort.Open();  //开启串口
                Thread.Sleep(200);
                lcMeter.ControlMachine(sp);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                //MessageBox.Show("端口 " + portName + " 打开失败！");             //开启失败，报错
                return false;
            }
            return true;
        }

        private string GetData()
        {
            try
            {
                byte[] readBuffer = new byte[this.sp.BytesToRead];
                this.sp.Read(readBuffer, 0, readBuffer.Length);
                return System.Text.Encoding.ASCII.GetString(readBuffer);
            }
            catch (IOException IOEx)
            {
                Logger.LogError(IOEx);
            }
            catch (InvalidOperationException IVOEx)
            {
                Logger.LogError(IVOEx);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
            return "";
        }



        //獲取端口和波特率
        private void GetPortBuad()
        {
            Settings.GetPortBuad(sp, Settings.MachineType.LC);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (isGettingData) return;
            string data = string.Empty;
            lblVoltage.Text = string.Empty;
            try
            {
                isGettingData = true;
                if (sp.IsOpen)
                {
                    data = GetData();
                    //Logger.LogMessage(data); //debug

                    if (!string.IsNullOrWhiteSpace(data))
                    {
                        List<double> listValue = lcMeter.AnalysisData(data);
                        if (listValue.Count == 2)
                        {
                            lblVoltage.Text = listValue[0].ToString();
                            lblLc.Text = listValue[1].ToString();
                        }
                    }

                    #region 已移到接口里
                    //if (!string.IsNullOrWhiteSpace(data))
                    //{
                    //    //16.0V, 0.245uA
                    //    //16.0V, 0.245uA
                    //    string[] trings1 = data.Split(new string[] { "\r\n" }, StringSplitOptions.None);
                    //    if (trings1 == null || trings1.Length == 0) return;

                    //    //16.0V, 0.245uA
                    //    //16.0V, 0.245uA
                    //    int rightIndex = -1;
                    //    for (int i = trings1.Length - 1; i > -1; i--)
                    //    {
                    //        if (trings1[i].Contains("V") && trings1[i].Contains("A"))
                    //        {
                    //            rightIndex = i;
                    //            break;
                    //        }
                    //    }

                    //    if (rightIndex == -1) return;
                    //    string[] strings = trings1[rightIndex].Split(',');

                    //    if (strings == null || strings.Length < 2) return;

                    //    if (strings[0].Contains("V"))
                    //        lblVoltage.Text = strings[0];

                    //    if (strings[1].Contains("A"))
                    //    {
                    //        decimal times = 1m;
                    //        if (strings[1].Contains("mA"))
                    //            times = 1000m;
                    //        else if (strings[1].Contains("uA"))
                    //            times = 1m;
                    //        else return;

                    //        string s = strings[1].Trim().Replace("mA", string.Empty).Replace("uA", string.Empty);
                    //        decimal value = 0m;
                    //        if (decimal.TryParse(s, out value))
                    //        {
                    //            value = value * times;
                    //            value = Math.Round(value, 2);
                    //            //if (value > 0m)
                    //            {
                    //                lblLc.Text = value.ToString();
                    //                return;
                    //            }
                    //        }
                    //    }
                    //}
                    #endregion
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                Logger.LogMessage(data);
            }
            finally
            {
                isGettingData = false;
#if DEBUG
                lblLc.Text = (RandomSugar.GetFormatedNumeric(9200, 15200) / 100m).ToString();
#endif
            }
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <returns></returns>
        private bool COMClose()
        {
            try
            {
                if (timer1.Enabled) timer1.Enabled = false;
                if (sp.IsOpen)
                {
                    Thread.Sleep(300);
                    sp.Close();
                }
                return true;
            }
            catch (System.Exception ex)
            {
                Logger.LogError(ex);
                return false;
            }
        }


        Stopwatch stopWatch = Stopwatch.StartNew();
        int chargeTime = 60;
        private void btnCharge_Click(object sender, EventArgs e)
        {
            try
            {
                timer1.Enabled = false;
                chargeTime = Convert.ToInt32(numChargeTime.Value);
                //Logger.LogMessage("chargeTime1" +chargeTime.ToString());
                //Thread.Sleep(200);
                lcMeter.SetCharTime(sp, numChargeTime.Value);
                //Thread.Sleep(200);
                //chargeTime = lcMeter.GetChargeTime(sp);
                //Logger.LogMessage("chargeTime2" + chargeTime.ToString());
                //if (chargeTime <= 0)
                //{
                //    chargeTime = Convert.ToInt32(numChargeTime.Value);
                //}

                Thread.Sleep(200);
                timer2.Enabled = true;
                lcMeter.SetVoltage(sp, numVoltage.Value);
                Thread.Sleep(200);
                lcMeter.Char(sp);
                stopWatch = Stopwatch.StartNew();
                //stopWatch.Start();
                isDischarged = false;
                timer1.Enabled = true;
                timer2.Enabled = true;

                btnTest.Focus();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
            finally
            {
#if DEBUG
                isTestting = true;
                timer1.Enabled = true;
                timer2.Enabled = true;
#endif
            }
        }

        private void btnDsicharge_Click(object sender, EventArgs e)
        {
            try
            {
                lblLc.Text = "0μA";
                timer1.Enabled = false;
                timer2.Enabled = false;
                lblCountDown.Text = "0";
                Thread.Sleep(300);
                isDischarging = true;
                isTestting = false;

                lcMeter.DisCharge(sp);
                isDischarged = true;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        double lastValue = 0;
        private void btnTest_Click(object sender, EventArgs e)
        {
            try
            {
                if (!isTestting)
                {
                    //已放到充电计时结束后
                    //timer1.Enabled = false;
                    //Thread.Sleep(200);
                    //lcMeter.Test(sp);

                    //isTestting = true;
                    //timer1.Enabled = true;
                }
                else
                {
                    if (_CurrentRowIndex > Grid.Rows.Count - 1) return;
                    double value = 0;
                    if (!double.TryParse(lblLc.Text, out value)) return;
                    //if (lastValue == value && value>0)
                    //{
                    //    Thread.Sleep(150);
                    //    if (!double.TryParse(lblLc.Text, out value)) return;
                    //}
                    if (lastValue == value) return;
                    lastValue = value;
                    //lsbLc.Items.Add(lblLc.Text);
                    //tssCount.Text = lsbLc.Items.Count.ToString();
                    //this.lsbLc.TopIndex = this.lsbLc.Items.Count - (int)(this.lsbLc.Height / this.lsbLc.ItemHeight);
                    int rowIndex = 0;
                    int columnIndex = 0;
                    if (this.Grid.CurrentCell == null)
                    {
                        this.Grid.Rows[0].Cells[ColLc.Index].Selected = true;
                        columnIndex = ColLc.Index;
                    }
                    else
                    {
                        rowIndex = this.Grid.CurrentCell.RowIndex;
                        columnIndex = this.Grid.CurrentCell.ColumnIndex;
                    }
                    ElectricViewModel view = this.Grid.CurrentRow.DataBoundItem as ElectricViewModel;
                    if (view != null)
                    {
                        if (this.Grid.Columns[columnIndex] == ColLc)
                        {
                            view.LC = value;
                            if (value > _StandardView.LcMax) view.LCisValid = false;
                            else view.LCisValid = true;
                        }
                        else if (this.Grid.Columns[columnIndex] == ColLc2)
                        {
                            view.LC2 = value;
                            if (value > _StandardView.LcMax) view.LC2isValid = false;
                            else view.LC2isValid = true;
                        }

                        this.Grid.Refresh();
                    }
                    try
                    {
                        if (_CurrentRowIndex + 1 <= this.Grid.Rows.Count - 1)
                            this.Grid.Rows[_CurrentRowIndex + 1].Cells[this.Grid.CurrentCell.ColumnIndex].Selected = true;
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex);
                    }

                    _CurrentRowIndex++;
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        //充電倒計時
        private void timer2_Tick(object sender, EventArgs e)
        {
            decimal time = chargeTime - stopWatch.ElapsedMilliseconds / 1000L;
            if (time <= 0m)
            {
                time = 0m;
                lblCountDown.Text = stringPass;
                stopWatch.Stop();
                timer1.Enabled = false;
                timer2.Enabled = false;

                Thread.Sleep(200);
                lcMeter.Test(sp);

                timer1.Enabled = true;
                isTestting = true;
                btnTest.Focus();
            }
            else lblCountDown.Text = time.ToString();
        }

        private void FormLC2311_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                SaveDefaultValue();

                if (!isDischarged) btnDsicharge_Click(null, null);
                isDischarged = true;
                IsClosing = true;
                if (isTestting)
                {
                    lcMeter.DisCharge(sp);
                    Thread.Sleep(200);
                }

            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
            try
            {
                Grid.EndEdit();
                var m = parentForm.GetType().GetMethod("RefreshTestGrid");
                if (m != null && m.GetParameters().Length == 1 
                    && !parentForm.IsDisposed
                    )
                    m.Invoke(parentForm, new object[] { 0 });
                else if ((m != null && m.GetParameters().Length == 2))
                    m.Invoke(parentForm, new object[] { null, false });
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                //MessageBox.Show(ex.Message, "異常S0025");
            }
        }

        private void tsmClear_Click(object sender, EventArgs e)
        {
            if (Grid.CurrentCell != null) Grid.CurrentCell.Value = null;
        }

        private void tsmClearColumn_Click(object sender, EventArgs e)
        {
            try
            {
                if (MessageBox.Show("即將清除當前列數據，請確認", "請確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)
                    == DialogResult.Cancel)
                    return;

                if (Grid.CurrentCell != null)
                {
                    int colmnIndex = Grid.CurrentCell.ColumnIndex;
                    for (int i = 0; i < Grid.Rows.Count; i++)
                    {
                        Grid.Rows[i].Cells[colmnIndex].Value = null;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                //MessageBox.Show(ex.Message, "異常S0035", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void SetLc2Visible(bool isVivible)
        {
            ColLc2.Visible = isVivible;
            Grid.Refresh();
        }

        bool isESCcancel = false;
        private void Grid_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            
            try
            {
                if (Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].ValueType == typeof(Double)
                    || Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].ValueType == typeof(Decimal))
                {
                    Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = 0;
                    e.Cancel = true;
                    SendKeys.Send("{ESC}");
                    isESCcancel = true;
                }
            }
            catch (Exception ex)
            {

            }
        }

        private void Grid_SelectionChanged(object sender, EventArgs e)
        {
            //if (!isTestting)
            {
                if (Grid.CurrentCell != null && Grid.CurrentCell.RowIndex < Grid.Rows.Count - 1)
                    _CurrentRowIndex = Grid.CurrentCell.RowIndex;
                else if (Grid.CurrentCell == null)
                    _CurrentRowIndex = 0;
            }
        }

        private void Grid_CellValidated(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                ElectricViewModel view = this.Grid.CurrentRow.DataBoundItem as ElectricViewModel;
                if (view == null) return;

                double value = 0;
                double.TryParse(Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(), out value);

                if (this.Grid.Columns[e.ColumnIndex] == ColLc)
                {
                    if (value > _StandardView.LcMax) view.LCisValid = false;
                    else view.LCisValid = true;
                }
                else if (this.Grid.Columns[e.ColumnIndex] == ColLc2)
                {
                    if (value > _StandardView.LcMax) view.LC2isValid = false;
                    else view.LC2isValid = true;
                }

                this.Grid.Refresh();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        public void RefreshGrid()
        {
            Grid.Refresh();
        }

        private void cboLevel_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (cboLevel.SelectedIndex == -1) return;
                string level = FormCommon.GetDataTableComboBoxValue(cboLevel);
                if (string.IsNullOrWhiteSpace(level)) return;
                lcMeter.SetLeak(sp, level);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        public new void SetChargeTime(int chargeTime)
        {
            numChargeTime.Value = chargeTime;
        }

        private void FormLC2311_Shown(object sender, EventArgs e)
        {
            if (ChargeTime > 0 && ChargeTime != 60)
            {
                numChargeTime.Value = ChargeTime;
                lcMeter.SetCharTime(sp, ChargeTime);
            }
        }

        private void Grid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (isESCcancel)
                {
                    isESCcancel = false;
                    if (e.RowIndex < Grid.Rows.Count - 1)
                    {

                        Grid.CurrentCell = Grid.Rows[e.RowIndex + 1].Cells[e.ColumnIndex];
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }
    }
}
